package com.xz.xzutils.utils;

import com.github.vertical_blank.sqlformatter.SqlFormatter;
import com.github.vertical_blank.sqlformatter.core.FormatConfig;
import com.manticore.jsqlformatter.JSQLFormatter;
import com.xz.xzutils.settings.mybatislogplus.MybatisLogPlusPersistentState;
import com.xz.xzutils.settings.mybatislogplus.MybatisLogPlusState;
import com.xz.xzutils.settings.mybatislogplus.constant.FormatterEnum;

import java.util.regex.Pattern;

/**
 * @author DONG.WANG17@HAND-CHINA.COM
 * @since 2025/2/28-02-28 22:31
 */
public class MySqlFormatter {
    private static final MybatisLogPlusState mybatisLogPlusState = MybatisLogPlusPersistentState.getInstance().getState();

    private MySqlFormatter() {
    }

    /**
     * 格式化 sql
     *
     * @param sql sql
     * @return 格式化 sql
     */
    public static String formatted(String sql, FormatterEnum formatterEnum) {
        try {
            if (FormatterEnum.SqlFormatter.equals(formatterEnum)) {
                return sqlFormatter(sql);
            } else if (FormatterEnum.JSQLFormatter.equals(formatterEnum)) {
                return jsqlFormatter(sql);
            }
            return sql;
        } catch (Exception e) {
            return sql;
        }
    }

    /**
     * 压缩sql
     *
     * @param sql sql
     * @return 压缩 sql
     */
    public static String compressed(String sql) {
        // 将多个空白字符(包括换行符)压缩为一个空白字符，单引号中不压缩
        String pattern = "('(?:[^']|'')*')|\\s+";
        return Pattern.compile(pattern)
                .matcher(sql)
                .replaceAll(mr -> mr.group(1) != null ? mr.group(1) : " ");
    }

    /**
     * 使用sql-formatter格式化sql
     *
     * @param sql sql
     * @return 格式化 sql
     */
    private static String sqlFormatter(String sql) {
        int indentNum = mybatisLogPlusState.getIndentNum();
        String indent = "    ";
        if (indentNum > 0) {
            indent = " ".repeat(indentNum);
        }
        String format;
        try {
            FormatConfig formatConfig = FormatConfig.builder()
                    .indent(indent)
                    .maxColumnLength(999999999)
                    .build();
            format = SqlFormatter.format(sql, formatConfig);
        } catch (Exception e) {
            format = sql;
        }
        return format;
    }

    /**
     * 使用jsql-formatter格式化sql
     *
     * @param sql sql
     * @return 格式化 sql
     * @throws Exception 异常
     */
    private static String jsqlFormatter(String sql) throws Exception {
        // 设置逗号尾随
        JSQLFormatter.setSeparation(JSQLFormatter.Separation.AFTER);
        //JSQLFormatter.setBackSlashQuoting(JSQLFormatter.BackSlashQuoting.YES);
        // 设置关键词
        JSQLFormatter.setKeywordSpelling(JSQLFormatter.Spelling.KEEP);
        JSQLFormatter.setFunctionSpelling(JSQLFormatter.Spelling.KEEP);
        // 设置对象拼写
        //JSQLFormatter.setObjectSpelling(JSQLFormatter.Spelling.KEEP);
        // 缩进
        JSQLFormatter.setIndentWidth(mybatisLogPlusState.getIndentNum());
        // 设置缩进字符
        // JSQLFormatter.setIndentString("    ");
        //JSQLFormatter.setOutputFormat(JSQLFormatter.OutputFormat.PLAIN);
        // 语句结束符号
        JSQLFormatter.setStatementTerminator(JSQLFormatter.StatementTerminator.NONE);
        // 设置括号
        // 启用方括号引用标识符
        JSQLFormatter.setSquaredBracketQuotation(JSQLFormatter.SquaredBracketQuotation.NO);

        // String[] options = new String[]{"showLineNumbers=" + JSQLFormatter.ShowLineNumbers.NO, "backSlashQuoting=" + JSQLFormatter.BackSlashQuoting.YES};
        // JSQLFormatter.applyFormattingOptions(options);

        return JSQLFormatter.format(sql);
    }
}
